{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "338ac0ea",
   "metadata": {},
   "source": [
    "# 数学运算 Math operation\n",
    "\n",
    "- Add / minus / multiply / divide\n",
    "\n",
    "- Matmul\n",
    "\n",
    "- Pow\n",
    "\n",
    "- Sqrt / rsqrt\n",
    "\n",
    "- Round"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b9efb814",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be5d40bc",
   "metadata": {},
   "source": [
    "### Add / minus / multiply / divide"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c89e6fc6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([3, 4])\n",
      "torch.Size([4])\n",
      "tensor([[0.7523, 0.6815, 1.6117, 1.0208],\n",
      "        [1.2276, 1.6346, 1.4006, 0.7490],\n",
      "        [0.9716, 0.9476, 1.6492, 1.5531]])\n",
      "tensor([[0.7523, 0.6815, 1.6117, 1.0208],\n",
      "        [1.2276, 1.6346, 1.4006, 0.7490],\n",
      "        [0.9716, 0.9476, 1.6492, 1.5531]])\n",
      "tensor(True)\n",
      "tensor(True)\n",
      "tensor(True)\n"
     ]
    }
   ],
   "source": [
    "a = torch.rand(3, 4)\n",
    "b = torch.rand(4)\n",
    "print(a.shape)\n",
    "print(b.shape)\n",
    "\n",
    "print(a + b)\n",
    "\n",
    "print(torch.add(a, b))\n",
    "\n",
    "print(torch.all(torch.eq(a - b, torch.sub(a, b))))\n",
    "\n",
    "print(torch.all(torch.eq(a * b, torch.mul(a, b))))\n",
    "\n",
    "print(torch.all(torch.eq(a / b, torch.div(a, b))))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e09180c",
   "metadata": {},
   "source": [
    "### Matmul 矩阵相乘"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "945792ba",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[3., 3.],\n",
      "        [3., 3.]])\n",
      "tensor([[1., 1.],\n",
      "        [1., 1.]])\n",
      "tensor([[6., 6.],\n",
      "        [6., 6.]])\n",
      "tensor([[6., 6.],\n",
      "        [6., 6.]])\n",
      "tensor([[6., 6.],\n",
      "        [6., 6.]])\n"
     ]
    }
   ],
   "source": [
    "a = torch.tensor([[3., 3.], [3., 3.]])\n",
    "print(a)\n",
    "\n",
    "b = torch.ones(2, 2)\n",
    "print(b)\n",
    "\n",
    "print(torch.mm(a, b))\n",
    "\n",
    "print(torch.matmul(a, b))\n",
    "\n",
    "# 和matmul结果相同\n",
    "print(a @ b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ecd19940",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 512])\n"
     ]
    }
   ],
   "source": [
    "# 神经网络 - 线性层举例\n",
    "# 4张照片打平\n",
    "a = torch.rand(4, 784)\n",
    "x = torch.rand(4, 784)\n",
    "w = torch.rand(512, 784)\n",
    "\n",
    "# 线性层 前向运算流程\n",
    "# x@w.t() + b\n",
    "print((x@w.t()).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "673b659b",
   "metadata": {},
   "source": [
    "### 2d tensor matmul\n",
    "\n",
    "多维矩阵乘法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "256616a2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([4, 3, 28, 32])\n",
      "torch.Size([4, 3, 28, 32])\n"
     ]
    }
   ],
   "source": [
    "a = torch.rand(4, 3, 28, 64)\n",
    "b = torch.rand(4, 3, 64, 32)\n",
    "\n",
    "# print(torch.mm(a, b).shape)\n",
    "\n",
    "print(torch.matmul(a, b).shape)\n",
    "\n",
    "b = torch.rand(4, 1, 64, 32)\n",
    "print(torch.matmul(a, b).shape)\n",
    "\n",
    "# 高维相乘，必须有一个是\n",
    "b = torch.rand(4, 64, 32)\n",
    "# print(torch.matmul(a, b).shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07866a14",
   "metadata": {},
   "source": [
    "### Power 开方运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "bbf9b91b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[3, 3],\n",
      "        [3, 3]])\n",
      "tensor([[9, 9],\n",
      "        [9, 9]])\n",
      "tensor([[9, 9],\n",
      "        [9, 9]])\n",
      "tensor([[3., 3.],\n",
      "        [3., 3.]])\n",
      "tensor([[0.3333, 0.3333],\n",
      "        [0.3333, 0.3333]])\n",
      "tensor([[3., 3.],\n",
      "        [3., 3.]])\n"
     ]
    }
   ],
   "source": [
    "a = torch.full([2, 2], 3)\n",
    "print(a)\n",
    "\n",
    "print(a.pow(2))\n",
    "\n",
    "print(a ** 2)\n",
    "\n",
    "aa = a ** 2\n",
    "print(aa.sqrt())\n",
    "\n",
    "print(aa.rsqrt())\n",
    "\n",
    "print(aa ** (0.5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a015113a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[2.7183, 2.7183],\n",
      "        [2.7183, 2.7183]])\n",
      "tensor([[1., 1.],\n",
      "        [1., 1.]])\n"
     ]
    }
   ],
   "source": [
    "a = torch.exp(torch.ones(2, 2))\n",
    "print(a)\n",
    "\n",
    "print(torch.log(a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "948fc73d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(3.) tensor(4.) tensor(3.) tensor(0.1400)\n",
      "tensor(3.)\n",
      "tensor(4.)\n"
     ]
    }
   ],
   "source": [
    "# .floor() .ceil() .round() .trunc() .frac()\n",
    "\n",
    "a = torch.tensor(3.14)\n",
    "\n",
    "print(a.floor(), a.ceil(), a.trunc(), a.frac())\n",
    "\n",
    "a = torch.tensor(3.499)\n",
    "\n",
    "print(a.round())\n",
    "\n",
    "a = torch.tensor(3.5)\n",
    "\n",
    "print(a.round())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "71981fda",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(11.9765)\n",
      "tensor(6.6503)\n",
      "tensor([[10.0000, 11.9765, 10.0451],\n",
      "        [10.0000, 10.0000, 10.0000]])\n",
      "tensor([[ 0.5861, 11.9765, 10.0451],\n",
      "        [ 6.6273,  9.5422,  6.6503]])\n",
      "tensor([[ 0.5861, 10.0000, 10.0000],\n",
      "        [ 6.6273,  9.5422,  6.6503]])\n"
     ]
    }
   ],
   "source": [
    "# clamp 裁剪\n",
    "# 比如：梯度裁剪\n",
    "\n",
    "grad = torch.rand(2,3) * 15\n",
    "\n",
    "print(grad.max())\n",
    "\n",
    "print(grad.median())\n",
    "\n",
    "print(grad.clamp(10))\n",
    "\n",
    "print(grad)\n",
    "\n",
    "# 裁剪范围 0 - 10\n",
    "print(grad.clamp(0, 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "de274be0",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
